#include "ctr_mode.h"

/* increment counter (128-bit int) by 1 */
static void ctr128_inc(unsigned char* counter)
{
    U32 n = 16, c = 1;

    do
    {
        --n;
        c += counter[n];
        counter[n] = (U8)c;
        c >>= 8;
    } while(n);
}

int C_CTR_MODE::Encrypt(BYTE* pIn, int iLenIn, BYTE* pOut, int* piLenOut, IBlockCipherKernel* pobjKer)
{
    int iBlock  = pobjKer->GetBlockLen();
    int& iWrite = *piLenOut;

    iWrite = 0;
    while(iWrite + iBlock <= iLenIn)
    {
        pobjKer->Encrypt(m_bfIV, pOut + iWrite);
        ctr128_inc(m_bfIV);

        for(int i = 0; i < 16; i++) pOut[iWrite + i] ^= pIn[iWrite + i];
        iWrite += iBlock;
    }

    return 0;
}

int C_CTR_MODE::Decrypt(BYTE* pIn, int iLenIn, BYTE* pOut, int* piLenOut, IBlockCipherKernel* pobjKer) { return Encrypt(pIn, iLenIn, pOut, piLenOut, pobjKer); }
